﻿using System;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;

namespace NColony.Dependencies.Contracts
{
    /// <summary>
    /// Interface for managing class dependencies.
    /// </summary>
    [ContractClass(typeof(IDependencyManagerContract))]
    public interface IDependencyManager
    {
        /// <summary>
        /// Resolves the dependencies.
        /// </summary>
        /// <param name="objectsWithDependencies">The objects with dependencies.</param>
        [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "objects", Justification = "Cannot assume to know what an IoC container might require. MEF uses object[]")]
        void ResolveDependencies(params object[] objectsWithDependencies);

        /// <summary>
        /// Creates a lazy instance.
        /// </summary>
        /// <typeparam name="T">The type of instance to create.</typeparam>
        /// <returns>A lazy instance.</returns>
        Lazy<T> CreateLazyInstance<T>();

        /// <summary>
        /// Creates the lazy instance.
        /// </summary>
        /// <typeparam name="T">The type of instance to create.</typeparam>
        /// <param name="dependencyLookupKey">The dependency lookup key.</param>
        /// <returns>A lazy instance.</returns>
        Lazy<T> CreateLazyInstance<T>(string dependencyLookupKey);

        /// <summary>
        /// Creates the instance or default.
        /// </summary>
        /// <typeparam name="T">The type of instance to create.</typeparam>
        /// <returns>An instance if found, otherwise null.</returns>
        T CreateInstanceOrDefault<T>();

        /// <summary>
        /// Creates the instance or default.
        /// </summary>
        /// <typeparam name="T">The type of instance to create.</typeparam>
        /// <param name="dependencyLookupKey">The dependency lookup key.</param>
        /// <returns>An instance if found, otherwise null.</returns>
        T CreateInstanceOrDefault<T>(string dependencyLookupKey);

        /// <summary>
        /// Creates the instance.
        /// </summary>
        /// <typeparam name="T">The type of instance to create.</typeparam>
        /// <returns>An instance if found, otherwise throws an Exception.</returns>
        T CreateInstance<T>();

        /// <summary>
        /// Creates the instance.
        /// </summary>
        /// <typeparam name="T">The type of instance to create.</typeparam>
        /// <param name="dependencyLookupKey">The dependency lookup key.</param>
        /// <returns>An instance if found, otherwise throws an Exception.</returns>
        T CreateInstance<T>(string dependencyLookupKey);
    }
}
